home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 235_02 / scantree.c < prev    next >
Text File  |  1987-06-16  |  4KB  |  108 lines

  1. /*  003  14-Feb-87  scantree.c
  2.  
  3.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include "ov.h"                /* only needed for Strdup() define */
  7. #include "dosfile.h"
  8.  
  9. #ifndef NULL
  10. #define NULL (0)
  11. #endif
  12.  
  13. static char *scanpath;
  14. static int (*scanfunc)(), scanattr, firstime;
  15.  
  16. struct scanent { struct scanent *next; char *name; };
  17.  
  18. char *strrchr(), *strupr();
  19. struct search_block *nxtfile();
  20.  
  21. /******************************************************************************
  22.                                S C A N T R E E
  23.  *****************************************************************************/
  24.  
  25. scantree(dir,pathbuf,attrib,func)  /* scan the specified dir tree */
  26. char *dir, *pathbuf;
  27. int attrib, (*func)();
  28. {
  29.    /* caller must initialize pathbuf - put in the drive spec, e.g. "C:"
  30.       if starting at the root and dir names are going to be processed */
  31.  
  32.    scanfunc = func;                    /* ptr to function called with names */
  33.    scanattr = attrib;                  /* attributes to scan for */
  34.    scanpath = pathbuf;                 /* dir name work buffer */
  35.  
  36.    walk(dir);                          /* walk the dir tree */
  37. }
  38.  
  39. /******************************************************************************
  40.                                    W A L K
  41.  *****************************************************************************/
  42.  
  43. walk(dirname)          /* walk the dir tree */
  44. char *dirname;
  45. {
  46.    int pathlen;
  47.    struct scanent *subdirs = NULL;
  48.    register struct search_block *sbp;
  49.    register struct scanent *nsub = (struct scanent *) &subdirs;
  50.  
  51.    /* build the pathname of the dir to scan */
  52.  
  53.    pathlen = strlen(scanpath);         /* remember callers length */
  54.    if (strcmp(dirname,"\\") != 0) {    /* special case if root dir */
  55.       strcat(scanpath,dirname);        /* add name of dir to scan */
  56.       strcat(scanpath,"\\");
  57.    } else                              /* starting at root */
  58.       strcat(scanpath,dirname);        /* add root to scanpath */
  59.  
  60.    /* tell users routine what dir is about to be scanned, only scan it if
  61.       users routine returns a NZ value - skip this one if 0 - note that the
  62.       dir names all have trailing \'s when passed to user */
  63.  
  64.    if ((*scanfunc)(NULL,scanpath)) {   /* tell user what dir it is (has \) */
  65.  
  66.       strcat(scanpath,"*.*");          /* add wildcard string */
  67.  
  68.       /* scan all files in directory, call scanfunc to process each file entry,
  69.          stack the names of any subdirectories so we can then scan them later */
  70.  
  71.       firstime = 1;
  72.  
  73.       while (sbp = nxtfile(scanpath,scanattr,&firstime)) {
  74.  
  75.          if ((*scanfunc)(sbp,NULL) == 0)  /* let somebody else see it */
  76.             break;                        /* skip the rest if they say stop */
  77.  
  78.          /* if this is a subdir to also scan, build a scanent for it */
  79.  
  80.          if (sbp->attrib & 0x10 && *sbp->fn != '.')
  81.             if (nsub->next = (struct scanent *) Malloc(sizeof(struct scanent))) {
  82.                nsub = nsub->next;
  83.                nsub->next = NULL;
  84.                nsub->name = Strdup(sbp->fn);
  85.             }
  86.       }
  87.    }
  88.  
  89.    /* if any subdirectories were found, scan 'em.  This isn't done
  90.       earlier so the file search isn't complicated by the directory
  91.       switches. */
  92.  
  93.    if (nsub = subdirs) {                       /* NULL if no sub's found */
  94.       scanpath[strlen(scanpath)-3] = '\0';     /* remove *.* for next level */
  95.       do {
  96.          walk(nsub->name);             /* call ourselves to scan this subtree */
  97.          free(nsub->name);             /* release sub dir name space   */
  98.          subdirs = nsub;               /* eat our own tail as we crawl */
  99.          nsub = nsub->next;            /*   down the list of subdirs   */
  100.          free((char *)subdirs);        /*   you can't go home again    */
  101.       } while (nsub);                  /* do all the subs found above  */
  102.    }
  103.  
  104.    scanpath[pathlen] = '\0';           /* restore dir pathname for caller */
  105. }
  106.  
  107.  
  108.